home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / Shareware Internet / Desarrolladores / gray image 2.1 / SimpleWindow.cc < prev    next >
Text File  |  1995-07-30  |  9KB  |  326 lines

  1. /*
  2.  ***********************************************************************
  3.  *
  4.  *
  5.  *            Simple Window Class
  6.  *        
  7.  *
  8.  ***********************************************************************
  9.  */
  10.  
  11. #include "image.h"
  12. #include "mymenv.h"
  13. #include "window.h"
  14. #include <PictUtil.h>
  15.  
  16. /*
  17.  *----------------------------------------------------------------------
  18.  *                Service functions
  19.  */
  20.  
  21.                 // Getting a bounding rectangle of an image
  22. ScreenRect::ScreenRect(const IMAGE& image)
  23. {
  24.   top = 0;
  25.   bottom = top + image.q_nrows();
  26.   left = 0;
  27.   right = left + image.q_ncols();
  28. }
  29.  
  30.                 // Create a rectangle of given height/width
  31.                 // positioned at the origin
  32. ScreenRect::ScreenRect(const rowcol& heightwidth)
  33. {
  34.   left = top = 0;
  35.   bottom = heightwidth.row();
  36.   right  = heightwidth.col();
  37. }
  38.  
  39.                     // Create a rectangle of given height/width
  40.                     // positioned at a given point
  41. ScreenRect::ScreenRect(const rowcol& origin, const rowcol& heightwidth)
  42. {
  43.   top  = origin.row();
  44.   left = origin.col();
  45.   bottom = top+heightwidth.row();
  46.   right  = left+heightwidth.col();
  47. }
  48.  
  49.  
  50.                     // Shifting a rectangle by the same amount
  51.                     // in X and Y
  52. ScreenRect& ScreenRect::operator += (const int offset)
  53.   top += offset; bottom += offset; left += offset; right += offset;
  54.   return *this;
  55. }
  56.  
  57.  
  58.                     // Print what rectangle is this
  59. void ScreenRect::print(const char * title) const
  60. {
  61.   alert("Rectangle %s (%d,%d) - (%d,%d)",title,top,left,bottom,right);
  62. }
  63.  
  64.  
  65.  
  66.  
  67. /*
  68.  *----------------------------------------------------------------------
  69.  *    A generic simple window that can be dragged around the screen
  70.  *        and closed by clicking a "go-away" button
  71.  * No other events are handled, redefine the event handler if necessary.
  72.  */
  73.  
  74.                 // Create a color window of the specified size and title
  75.                 // Note, the upper left corner of 'rect' must
  76.                 // NOT be (0,0)!
  77. ScreenWindow::ScreenWindow(ScreenRect rect, const char * title)
  78. {
  79.   const int window_offset = 100;        // Cannot be 0 or small!
  80.   this_window = NewCWindow(nil,rect += window_offset,(Pstr)title,
  81.                TRUE,noGrowDocProc,
  82.                (WindowPtr)(-1),TRUE,(long)this);
  83.   assert( this_window != 0 );
  84.   SetPort(this_window);
  85.   SelectWindow(this_window);
  86. }
  87.  
  88.                 // Create a color window from a resource template
  89. ScreenWindow::ScreenWindow(const short resource_id)
  90. {
  91.   this_window = GetNewCWindow(resource_id,nil,(WindowPtr)(-1));
  92.   SetWRefCon(this_window,(long)this);
  93.   assert( this_window != 0 );
  94.   SetPort(this_window);
  95.   SelectWindow(this_window);
  96. }
  97.  
  98.  
  99.  
  100.                 // Close the window and clean up the rubble
  101. ScreenWindow::~ScreenWindow(void)
  102. {
  103.   assert( this_window != 0 );
  104.   DisposeWindow(this_window);
  105.   this_window = 0;
  106. }
  107.  
  108.  
  109.                 // Event handling loop. Returns only when the
  110.                 // window is to be destroyed
  111. void ScreenWindow::handle(void)
  112. {
  113.   const long event_timeout = 20;
  114.   EventRecord    theEvent;
  115.  
  116.   for(;;)
  117.   {
  118.     if( !WaitNextEvent(everyEvent, &theEvent, event_timeout, nil) )
  119.      if( handle_null_event(theEvent.when) )
  120.        continue;
  121.      else
  122.        return;
  123.     switch( theEvent.what )
  124.     {
  125.       case kHighLevelEvent:    // All High-level events we're going to receive
  126.            // do_well( AEProcessAppleEvent(&theEvent) ); // are Apple events
  127.            break;
  128.  
  129.       case mouseDown:
  130.        if( !handle_mouse_down(theEvent) )
  131.          return;        // Window is to be closed (go-away buttin clicked)
  132.        break;
  133.             
  134.       case updateEvt:
  135.        if( this_window == (WindowPtr)theEvent.message )
  136.          update();
  137.        break;
  138.  
  139.       case keyDown:
  140.       case autoKey:
  141.        if( !handle_key_down(theEvent) )
  142.          return;        // a "quit" key must've been pressed
  143.        break;
  144.                         
  145.       case activateEvt:
  146.        if( this_window == (WindowPtr)theEvent.message )
  147.          activate(theEvent.modifiers & 0x01);
  148.        break;
  149.       }  
  150.   }
  151. }
  152.  
  153.                 // Handle "mouse-down" events
  154.                 // Returns FALSE if the user clicked within the
  155.                 // go-away region of our window. Otherwise,
  156.                 // returns TRUE
  157.                 // Handles dragging if necessary and system clicks
  158. Boolean ScreenWindow::handle_mouse_down(const EventRecord& the_event)
  159. {
  160.   WindowPtr    wp;
  161.   short        windowPart = FindWindow (the_event.where, &wp);
  162.     
  163.   switch (windowPart)
  164.   {
  165.     case inSysWindow: 
  166.          SystemClick(&the_event, wp);
  167.      break;
  168.         
  169.     case inMenuBar:
  170.          break;                // Don't handle it yet
  171.  
  172.     case inContent:
  173.      break;
  174.           
  175.     case inDrag:
  176.      if( wp == this_window )
  177.        drag(the_event.where);
  178.      break;
  179.                       
  180.     case inGoAway:
  181.      return FALSE;
  182.   }
  183.   return TRUE;
  184. }
  185.  
  186.                 // Handles key_down & auto_key events. Return FALSE
  187.                 // if the window is to be closed down
  188. Boolean ScreenWindow::handle_key_down(const EventRecord& the_event)
  189. {
  190.   return FALSE;                // Any key kills the application, sorry
  191. }
  192.  
  193.  
  194.                 // Handles null events, when nothing happens for some
  195.                 // time. Return FALSE when it's time to die
  196. Boolean ScreenWindow::handle_null_event(const long event_time)
  197. {
  198.   return TRUE;                            // Keep going
  199. }
  200.  
  201.             // Private window parts
  202.                 // Handle an update event - redraw the window
  203.                 // A virtual function draw() is called to do
  204.                 // the actual redrawing
  205. void ScreenWindow::update(void)
  206. {
  207.   GrafPtr    savePort;
  208.     
  209.   GetPort(&savePort);
  210.   SetPort(this_window);
  211.   BeginUpdate(this_window);
  212.   draw();
  213.   EndUpdate(this_window);
  214.   SetPort(savePort);
  215. }
  216.  
  217.                 // Make the entire window being redrawn
  218. void ScreenWindow::refresh(void)
  219. {
  220. //    EraseRect(&this_window->portRect);
  221.   InvalRect(&this_window->portRect);            
  222. }
  223.  
  224.                 // Handle an activate or deactivate event
  225. void ScreenWindow::activate (const Boolean go_active)
  226. {
  227.   if( go_active )
  228.     SetPort(this_window);
  229. }
  230.  
  231.  
  232. /*
  233.  *----------------------------------------------------------------------
  234.  *        A simple window with an offscreen window buffer
  235.  */
  236.  
  237.                     // Allocate the buffer for the offscreen
  238.                     // drawing and load CLUT (if clut_id != 0)
  239. OffScreenWindow::OffScreenWindow
  240.     (ScreenRect rect, const char * title, const short clut_id)
  241.     : ScreenWindow(rect,title), graf_world(nil)
  242. {
  243.   CTabHandle clut_handle = nil;
  244.   if( clut_id != 0 )
  245.   {                // try to get a user CLUT with that resource id
  246.     clut_handle = GetCTable(clut_id);
  247.     assert( clut_handle != 0 );
  248.     SetWinColor(our_window(),(WinCTab**)clut_handle);
  249.   }
  250.   do_well( NewGWorld(&graf_world,8,rect,clut_handle,nil,0) );
  251.   assert( graf_world != (void *)0 );
  252.  
  253. //    if( clut_handle != nil )
  254. //      DisposCTable(clut_handle);        // CLUT has been copied, and can be disposed of now
  255.                 // But careful! CLUT is associated with the window
  256.                 // by SetWinColor(), so we don't dispose of it
  257.  
  258.                     // Get hold of the offscreen pixmap
  259.   pixmap = GetGWorldPixMap(graf_world);        // and make sure it looks like
  260.   assert( pixmap != nil && *pixmap != nil );    // we can use it
  261.  
  262.   assert( (**pixmap).cmpCount == 1 );            // We have a color table index
  263.   assert( !PixMap32Bit(pixmap) );
  264.  
  265.   _height = abs((**pixmap).bounds.top - (**pixmap).bounds.bottom);
  266.   _width  = abs((**pixmap).bounds.right - (**pixmap).bounds.left);
  267.   _bytes_per_row = (**pixmap).rowBytes & 0x7fff;
  268.  
  269.   assert( _height > 0 && _height < 10000 );         // Just to play safe
  270.   assert( _width > 0 && _width <= _bytes_per_row );    
  271.  
  272.   activate_palette();                    // Activate palette for the window
  273. }
  274.  
  275.                     // Dispose of the offscreen buffer
  276. OffScreenWindow::~OffScreenWindow(void)
  277. {
  278.   assert( graf_world != nil );
  279.   DisposeGWorld(graf_world);
  280.   graf_world = nil;
  281.   PaletteHandle window_palette = GetPalette(our_window());
  282.   if( window_palette != nil )        // dispose of our palette if was allocated
  283.   {
  284.     SetPalette(our_window(),nil,FALSE);
  285.     DisposePalette(window_palette);
  286.   }
  287.   pixmap = nil;
  288.   _height = _width = _bytes_per_row = 0;
  289. }
  290.  
  291.             // Make sure that the colors of our off-screen
  292.             // buffer would be displayed properly (or close enough)
  293.             // on screen
  294. void OffScreenWindow::activate_palette(void)
  295. {
  296.   CTabHandle window_ctab = (**pixmap).pmTable;
  297.   assert( window_ctab != nil && *window_ctab != nil );
  298.  
  299.   PaletteHandle palette = NewPalette((**window_ctab).ctSize,window_ctab,pmTolerant+pmExplicit,0);
  300.   assert( palette != nil );
  301.   SetPalette(our_window(),palette,TRUE);
  302.   do_well( QDError() );
  303.   ActivatePalette(our_window());    
  304.   do_well( QDError() );
  305. }
  306.  
  307.  
  308.             // Get a bounding rectangle for the window
  309. ScreenRect OffScreenWindow::q_bounds(void) const
  310. {
  311.   return (**pixmap).bounds;
  312. }
  313.  
  314.  
  315.                 // Actual drawing - moving the picture from the
  316.                 // offscreen grafworld to the onscreen one
  317. void OffScreenWindow::draw(void)
  318. {
  319.   assert( LockPixels(pixmap) );
  320.   Rect& pixmap_rect = (**pixmap).bounds;
  321.   CopyBits((const BitMap *)*pixmap, &qd.thePort->portBits, &pixmap_rect, 
  322.         &our_window()->portRect, /*ditherCopy*/ srcCopy, nil);
  323.   UnlockPixels(pixmap);
  324. }
  325.